﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace AudiPyme.DAL
{
    public class InstanciaTiposActivosVulnerabilidadesFactory
    {
        //Método que elimina un conjunto de relaciones Tipo de Activo - Vulnerabilidad actuales de una empresa
        public static void EliminaInstanciaTipActVuln(int IdTipoActivo, int IdVulnerabilidad, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            InstanciaTiposActivosVulnerabilidades nuevaInstancia =
                new InstanciaTiposActivosVulnerabilidades();
            nuevaInstancia.IdEmpresa = IdEmpresa;
            nuevaInstancia.IdTipoActivo = IdTipoActivo;
            nuevaInstancia.IdVulnerabilidad = IdVulnerabilidad;
            InstanciaTiposActivosVulnerabilidades InstanciaEliminar
                        = (from InstTipActVuln in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                           where InstTipActVuln.IdTipoActivo == nuevaInstancia.IdTipoActivo &&
                                 InstTipActVuln.IdVulnerabilidad == nuevaInstancia.IdVulnerabilidad && InstTipActVuln.Actual == true
                           select InstTipActVuln).First();
            InstanciaEliminar.Actual = false;
            agenteBD.SaveChanges();
        }

        //Método que elimina (borrado lógico, las pone a false) todas las ocurrencias de relaciones con IdTipoActivo, IdVulnerabilidad de una Empresa
        public static void EliminarInstanciaTipActVuln(int IdEmpresa, int IdTipoActivo, int IdVulnerabilidad)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<InstanciaTiposActivosVulnerabilidades> InstanciaEliminar = from InstTipActVuln in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                                  where InstTipActVuln.IdTipoActivo == IdTipoActivo &&
                                                                                        InstTipActVuln.IdVulnerabilidad == IdVulnerabilidad &&
                                                                                        InstTipActVuln.IdEmpresa == IdEmpresa
                                                                                  select InstTipActVuln;

            //Eliminamos todas las ocurrencias de relaciones con IdTipoActivo, IdVulnerabilidad
            foreach (InstanciaTiposActivosVulnerabilidades InstElim in InstanciaEliminar)
            {
                InstElim.Actual = false;
            }
            agenteBD.SaveChanges();
        }

        //Método que inserta una nueva instancia tipo activo - vulnerabilidad asociada a una empresa
        public static void InsertarInstanciaTipActVuln(int IdEmpresa, int IdTipoActivo, int IdVulnerabilidad)
        {
            InstanciaTiposActivosVulnerabilidades nuevaInstancia = new InstanciaTiposActivosVulnerabilidades();
            nuevaInstancia.IdEmpresa = IdEmpresa;
            nuevaInstancia.IdTipoActivo = IdTipoActivo;
            nuevaInstancia.IdVulnerabilidad = IdVulnerabilidad;
            //Ponemos Actual=true ya que es una relación que actualmente está seleccionada por la empresa
            nuevaInstancia.Actual = true;
            InstanciaTiposActivosVulnerabilidadesFactory.InsertarInstanciaTipActVuln(nuevaInstancia, IdEmpresa);
        }

        //Método que inserta una nueva relación Tipo Activo - Vulnerabilidad 
        //(Comprueba si estaba insertada anteriormente pero con Actual=false y si es así sólo cambia ese atributo)
        public static void InsertarInstanciaTipActVuln(InstanciaTiposActivosVulnerabilidades instancia, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            if (EstaHistoricoInstanciaTipActVuln(instancia, IdEmpresa))
            {
                InstanciaTiposActivosVulnerabilidades Instancia = (from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                   where i.IdTipoActivo == instancia.IdTipoActivo &&
                                                                   i.IdVulnerabilidad == instancia.IdVulnerabilidad &&
                                                                   i.IdEmpresa == IdEmpresa
                                                                   select i).First();
                Instancia.Actual = true;
            }
            else
            {
                agenteBD.AddToInstanciaTiposActivosVulnerabilidadesEstablecer(instancia);
            }
            agenteBD.SaveChanges();
        }

        //Método que comprueba si una relación Tipo Activo - Vulnerabilidad está en el Histórico de la Empresa
        public static bool EstaHistoricoInstanciaTipActVuln(InstanciaTiposActivosVulnerabilidades instancia, int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<InstanciaTiposActivosVulnerabilidades> LRelacion = (from i in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                     where i.IdTipoActivo == instancia.IdTipoActivo &&
                                                                     i.IdVulnerabilidad == instancia.IdVulnerabilidad &&
                                                                     i.IdEmpresa == IdEmpresa
                                                                     select i).ToList();
            //Si no se recoge nada es que la relación no estuvo anteriormente seleccionada por la empresa (Histórico)
            if (LRelacion.Count == 0)
            {
                return false;
            }
            //Si no, es porque la empresa tuvo seleccionada esa relación anteriormente (Actual=false)
            else
            {
                return true;
            }
        }

        //Método que recoge el número de relaciones Tipo Activo - Vulnerabilidad actuales de una empresa
        public static int NumRelacTipActVuln(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int nRelac = (from InstTipAmenVuln in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                          where InstTipAmenVuln.IdEmpresa == IdEmpresa && InstTipAmenVuln.Actual == true
                          select InstTipAmenVuln).Count();
            return nRelac;
        }

        //Método que recoge el número de relaciones Tipo Activo - Vulnerabilidad actuales de un Informe
        public static int NumRelacTipActVulnInforme(int IdInforme)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int nRelac = (from InstTipAmenVulnInf in agenteBD.InstanciaTipactVulnInformeEstablecer
                          where InstTipAmenVulnInf.IdInforme == IdInforme
                          select InstTipAmenVulnInf).Count();
            return nRelac;
        }

        //Métod que recoge la lista de nombres de las relaciones Tipo Activo-Vulnerabilidad actuales de una empresa
        public static List<String> ListaTiposActivosVulnEmpresa(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<String> LTipActivVulnEmp = new List<String>();
            IQueryable<String> TiposActEmpr = (from InstTipActVuln in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                               join TipActiv in agenteBD.TiposActivosEstablecer
                                                    on InstTipActVuln.IdTipoActivo equals TipActiv.IdTipoActivo
                                               where InstTipActVuln.IdEmpresa == IdEmpresa && InstTipActVuln.Actual == true
                                               orderby InstTipActVuln.IdTipoActivo
                                               select TipActiv.TipoActivo).Distinct();
            foreach (String TipoActivoEmpresa in TiposActEmpr)
            {
                LTipActivVulnEmp.Add(TipoActivoEmpresa);
            }
            return LTipActivVulnEmp;
        }

        //Método que saca el número de relaciones Tipo Activo-Vulnerabilidad actuales ordenadas por Tipo Activo
        public static List<int> ListaNumTipActivVulnEmpr(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            List<int> LNumTipActivVulnEmp = new List<int>();
            //Sacamos todos los Id's de los Tipos de Activos de las relaciones 
            //Tipo Activo-Vulnerabilidad Seleccionados por la Empresa
            IQueryable<int> NumIdsTiposActEmpr = (from InstTipActVuln in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                  where InstTipActVuln.IdEmpresa == IdEmpresa && InstTipActVuln.Actual == true
                                                  orderby InstTipActVuln.IdTipoActivo
                                                  select InstTipActVuln.IdTipoActivo).Distinct();
            //De todos los Id's de Tipo de Activo de la Empresa, contamos cuantas relaciones
            //TipoActivo-Vulnerabilidad eligio la empresa con ese Tipo Activo
            foreach (int IdTipActEmp in NumIdsTiposActEmpr)
            {
                int NumTipActVulnEmp = (from InstTipActVuln in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                        where InstTipActVuln.IdEmpresa == IdEmpresa &&
                                              InstTipActVuln.IdTipoActivo == IdTipActEmp
                                        orderby InstTipActVuln.IdTipoActivo
                                        select InstTipActVuln.IdTipoActivo).Count();
                LNumTipActivVulnEmp.Add(NumTipActVulnEmp);
            }
            return LNumTipActivVulnEmp;
        }

        //Recoge el número de relaciones Tipo Activo-Vulnerabilidades que tiene la empresa con un IdTipoActivo dado
        public static int NumRelacionesTipoActVulnPorTipoActivo(int IdEmpresa, int IdTipoActivo)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumRelaciones = (from Rel in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                 where Rel.IdEmpresa == IdEmpresa && Rel.IdTipoActivo == IdTipoActivo && Rel.Actual == true
                                 select Rel).Count();
            return NumRelaciones;

        }

        //Método que hace un borrado lógico de las Instancias Tipo Activo - Vulnerabilidad de una lista de relaciones de ese tipo
        internal static List<InstanciaTiposActivosVulnerabilidades> EliminaInstanciaPorRelacTipActVuln(List<Matriz_TiposActivosVulnerabilidades> LRelTipActVulnPorVuln)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<InstanciaTiposActivosVulnerabilidades> LRelacionesEliminadas = new List<InstanciaTiposActivosVulnerabilidades>();
            foreach (Matriz_TiposActivosVulnerabilidades Rel in LRelTipActVulnPorVuln)
            {
                //Recogemos las Instancias actuales 
                IQueryable<InstanciaTiposActivosVulnerabilidades> InstTipActVuln = from Instanc in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                                   where Instanc.IdTipoActivo == Rel.IdTipoActivo && Instanc.IdVulnerabilidad == Rel.IdVulnerabilidad &&
                                                                                     Instanc.Actual == true
                                                                                   select Instanc;
                if (InstTipActVuln.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a false
                    foreach (InstanciaTiposActivosVulnerabilidades Instancia in InstTipActVuln)
                    {
                        Instancia.Actual = false;
                        //Añadimos a la lista de Relaciones Eliminadas
                        LRelacionesEliminadas.Add(Instancia);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesEliminadas;
        }

        //Restaura todas las instancias asociadas a una lista de relaciones tipo activo - vulnerabilidad
        internal static List<InstanciaTiposActivosVulnerabilidades> RestauraInstanciaPorRelacTipActVuln(List<Matriz_TiposActivosVulnerabilidades> LRelTipActVulnPorVuln)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            //Por cada amenaza de la lista
            //Lista de aquellas relaciones a las que se le hacen un borrado lógico
            List<InstanciaTiposActivosVulnerabilidades> LRelacionesRestauradas = new List<InstanciaTiposActivosVulnerabilidades>();
            foreach (Matriz_TiposActivosVulnerabilidades Rel in LRelTipActVulnPorVuln)
            {
                //Recogemos las Instancias actuales 
                IQueryable<InstanciaTiposActivosVulnerabilidades> InstTipActAmenCrit = from Instanc in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                                       where Instanc.IdTipoActivo == Rel.IdTipoActivo && Instanc.IdVulnerabilidad == Rel.IdVulnerabilidad
                                                                                       select Instanc;
                if (InstTipActAmenCrit.Count() != 0)
                {
                    //Para cada uno actualizamos el Valor Actual a true
                    foreach (InstanciaTiposActivosVulnerabilidades Instancia in InstTipActAmenCrit)
                    {
                        Instancia.Actual = true;
                        //Añadimos a la lista de Relaciones Restauradas
                        LRelacionesRestauradas.Add(Instancia);
                    }
                }
            }
            agenteBD.SaveChanges();
            return LRelacionesRestauradas;
        }

        //Número total de instancias de relaciones Tipo Activo - Vulnerabilidad de una empresa
        internal static int NumeroTotalRelaciones(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            int NumRelaciones = (from Rel in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                 where Rel.IdEmpresa == IdEmpresa && Rel.Actual == true
                                 select Rel).Count();
            return NumRelaciones;
        }

        //Método que elimina de forma física todas las instancias Tipo Activo - Vulnerabilidad asociadas a una empresa
        internal static void EliminaTotalInstanciasTipVuln(int IdEmpresa)
        {
            ModeloContainer agenteBD = new ModeloContainer();
            IQueryable<InstanciaTiposActivosVulnerabilidades> InstanciasEliminarQuery = from Instancia in agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer
                                                                                        where Instancia.IdEmpresa == IdEmpresa
                                                                                        select Instancia;
            if (InstanciasEliminarQuery.Count() != 0)
            {
                foreach (InstanciaTiposActivosVulnerabilidades Inst in InstanciasEliminarQuery)
                {
                    agenteBD.InstanciaTiposActivosVulnerabilidadesEstablecer.DeleteObject(Inst);
                }
                agenteBD.SaveChanges();
            }
        }
    }
}
